home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cdrtools-1.10 / cdrecord / modes.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-30  |  6.4 KB  |  246 lines

  1. /* @(#)modes.c    1.15 00/07/30 Copyright 1988 J. Schilling */
  2. #ifndef lint
  3. static    char sccsid[] =
  4.     "@(#)modes.c    1.15 00/07/30 Copyright 1988 J. Schilling";
  5. #endif
  6. /*
  7.  *    SCSI mode page handling
  8.  *
  9.  *    Copyright (c) 1988 J. Schilling
  10.  */
  11. /*
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2, or (at your option)
  15.  * any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; see the file COPYING.  If not, write to
  24.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  */
  26.  
  27. #include <mconfig.h>
  28. #include <sys/types.h>
  29. #include <standard.h>
  30. #include <schily.h>
  31. #include <scg/scgcmd.h>
  32. #include <scg/scsireg.h>
  33. #include <scg/scsitransp.h>
  34.  
  35. #include "cdrecord.h"
  36.  
  37. EXPORT int    scsi_compliant;
  38.  
  39. LOCAL    BOOL    has_mode_page    __PR((SCSI *scgp, int page, char *pagename, int *lenp));
  40. EXPORT    BOOL    get_mode_params    __PR((SCSI *scgp, int page, char *pagename,
  41.                     u_char *modep, u_char *cmodep,
  42.                     u_char *dmodep, u_char *smodep,
  43.                     int *lenp));
  44. EXPORT    BOOL    set_mode_params    __PR((SCSI *scgp, char *pagename, u_char *modep,
  45.                     int len, int save, int secsize));
  46.  
  47. #define    XXX
  48.  
  49. #ifdef    XXX
  50. LOCAL
  51. BOOL has_mode_page(scgp, page, pagename, lenp)
  52.     SCSI    *scgp;
  53.     int    page;
  54.     char    *pagename;
  55.     int    *lenp;
  56. {
  57.     u_char    mode[0x100];
  58.     int    hdlen;
  59.     int    len = 1;                /* Nach SCSI Norm */
  60.     int    try = 0;
  61.     struct    scsi_mode_page_header *mp;
  62.  
  63. again:
  64.     fillbytes((caddr_t)mode, sizeof(mode), '\0');
  65.     if (lenp)
  66.         *lenp = 0;
  67.  
  68.     (void)test_unit_ready(scgp);
  69.     scgp->silent++;
  70. /* Maxoptix bringt Aborted cmd 0x0B mit code 0x4E (overlapping cmds)*/
  71.  
  72.     /*
  73.      * The Matsushita CW-7502 will sometimes deliver a zeroed
  74.      * mode page 2A if "Page n default" is used instead of "current".
  75.      */
  76.     if (mode_sense(scgp, mode, len, page, 0) < 0) {    /* Page n current */
  77.         scgp->silent--;
  78.         return (FALSE);
  79.     } else {
  80.         len = ((struct scsi_mode_header *)mode)->sense_data_len + 1;
  81.     }
  82.     if (mode_sense(scgp, mode, len, page, 0) < 0) {    /* Page n current */
  83.         scgp->silent--;
  84.         return (FALSE);
  85.     }
  86.     scgp->silent--;
  87.  
  88.     if (scgp->verbose)
  89.         scg_prbytes("Mode Sense Data", mode, len - scg_getresid(scgp));
  90.     hdlen = sizeof(struct scsi_mode_header) +
  91.             ((struct scsi_mode_header *)mode)->blockdesc_len;
  92.     mp = (struct scsi_mode_page_header *)(mode + hdlen);
  93.     if (scgp->verbose)
  94.         scg_prbytes("Mode Page  Data", (u_char *)mp, mp->p_len+2);
  95.  
  96.     if (mp->p_len == 0) {
  97.         if (!scsi_compliant && try == 0) {
  98.             len = hdlen;
  99.             /*
  100.              * add sizeof page header (page # + len byte)
  101.              * (should normaly result in len == 14)
  102.              * this allowes to work with:
  103.              *     Quantum Q210S    (wants at least 13)
  104.              *     MD2x        (wants at least 4)
  105.              */
  106.             len += 2;
  107.             try++;
  108.             goto again;
  109.         }
  110.         /* XXX if (!nowarn) */
  111.         errmsgno(EX_BAD,
  112.             "Warning: controller returns zero sized %s page.\n",
  113.                                 pagename);
  114.     }
  115.     if (!scsi_compliant &&
  116.         (len < (int)(mp->p_len + hdlen + 2))) {
  117.         len = mp->p_len + hdlen + 2;
  118.  
  119.         /* XXX if (!nowarn) */
  120.         errmsgno(EX_BAD,
  121.             "Warning: controller returns wrong size for %s page.\n",
  122.                                 pagename);
  123.     }
  124.     if (mp->p_code != page) {
  125.         /* XXX if (!nowarn) */
  126.         errmsgno(EX_BAD,
  127.             "Warning: controller returns wrong page %X for %s page (%X).\n",
  128.                         mp->p_code, pagename, page);
  129.         return (FALSE);
  130.     }
  131.  
  132.     if (lenp)
  133.         *lenp = len;
  134.     return (mp->p_len > 0);
  135. }
  136. #endif
  137.  
  138. EXPORT
  139. BOOL get_mode_params(scgp, page, pagename, modep, cmodep, dmodep, smodep, lenp)
  140.     SCSI    *scgp;
  141.     int    page;
  142.     char    *pagename;
  143.     u_char    *modep;
  144.     u_char    *cmodep;
  145.     u_char    *dmodep;
  146.     u_char    *smodep;
  147.     int    *lenp;
  148. {
  149.     int    len;
  150.     BOOL    ret = TRUE;
  151.  
  152. #ifdef    XXX
  153.     if (lenp)
  154.         *lenp = 0;
  155.     if (!has_mode_page(scgp, page, pagename, &len)) {
  156.         if (!scgp->silent) errmsgno(EX_BAD,
  157.             "Warning: controller does not support %s page.\n",
  158.                                 pagename);
  159.         return (FALSE);
  160.     }
  161.     if (lenp)
  162.         *lenp = len;
  163. #else
  164.     if (lenp == 0)
  165.         len = 0xFF;
  166. #endif
  167.  
  168.     if (modep) {
  169.         fillbytes(modep, 0x100, '\0');
  170.         if (mode_sense(scgp, modep, len, page, 0) < 0) {/* Page x current */
  171.             errmsgno(EX_BAD, "Cannot get %s data.\n", pagename);
  172.             ret = FALSE;
  173.         } else if (scgp->verbose) {
  174.             scg_prbytes("Mode Sense Data", modep, len - scg_getresid(scgp));
  175.         }
  176.     }
  177.  
  178.     if (cmodep) {
  179.         fillbytes(cmodep, 0x100, '\0');
  180.         if (mode_sense(scgp, cmodep, len, page, 1) < 0) {/* Page x change */
  181.             errmsgno(EX_BAD, "Cannot get %s mask.\n", pagename);
  182.             ret = FALSE;
  183.         } else if (scgp->verbose) {
  184.             scg_prbytes("Mode Sense Data", cmodep, len - scg_getresid(scgp));
  185.         }
  186.     }
  187.  
  188.     if (dmodep) {
  189.         fillbytes(dmodep, 0x100, '\0');
  190.         if (mode_sense(scgp, dmodep, len, page, 2) < 0) {/* Page x default */
  191.             errmsgno(EX_BAD, "Cannot get default %s data.\n",
  192.                                 pagename);
  193.             ret = FALSE;
  194.         } else if (scgp->verbose) {
  195.             scg_prbytes("Mode Sense Data", dmodep, len - scg_getresid(scgp));
  196.         }
  197.     }
  198.  
  199.     if (smodep) {
  200.         fillbytes(smodep, 0x100, '\0');
  201.         if (mode_sense(scgp, smodep, len, page, 3) < 0) {/* Page x saved */
  202.             errmsgno(EX_BAD, "Cannot get saved %s data.\n", pagename);
  203.             ret = FALSE;
  204.         } else if (scgp->verbose) {
  205.             scg_prbytes("Mode Sense Data", smodep, len - scg_getresid(scgp));
  206.         }
  207.     }
  208.  
  209.     return (ret);
  210. }
  211.  
  212. EXPORT
  213. BOOL set_mode_params(scgp, pagename, modep, len, save, secsize)
  214.     SCSI    *scgp;
  215.     char    *pagename;
  216.     u_char    *modep;
  217.     int    len;
  218.     int    save;
  219.     int    secsize;
  220. {
  221.     int    i;
  222.  
  223.     ((struct scsi_modesel_header *)modep)->sense_data_len    = 0;
  224.     ((struct scsi_modesel_header *)modep)->res2        = 0;
  225.  
  226.     i = ((struct scsi_mode_header *)modep)->blockdesc_len;
  227.     if (i > 0) {
  228.         i_to_3_byte(
  229.             ((struct scsi_mode_data *)modep)->blockdesc.nlblock,
  230.                                 0);
  231.         if (secsize >= 0)
  232.         i_to_3_byte(((struct scsi_mode_data *)modep)->blockdesc.lblen,
  233.                             secsize);
  234.     }
  235.  
  236.     if (save == 0 || mode_select(scgp, modep, len, save, scgp->inq->data_format >= 2) < 0) {
  237.         if (mode_select(scgp, modep, len, 0, scgp->inq->data_format >= 2) < 0) {
  238.             errmsgno(EX_BAD,
  239.                "Warning: using default %s data.\n", pagename);
  240.             scg_prbytes("Mode Select Data", modep, len);
  241.             return (FALSE);
  242.         }
  243.     }
  244.     return (TRUE);
  245. }
  246.